/* $Id$ */
/*
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#ifndef __PJMEDIA_MCX_STREAM_H__
#define __PJMEDIA_MCX_STREAM_H__

/**
 * @file mcx_stream.h
 * @brief Media Stream.
 */

#include <pjmedia/codec.h>
#include <pjmedia/endpoint.h>
#include <pjmedia/jbuf.h>
#include <pjmedia/port.h>
#include <pjmedia/rtcp.h>
#include <pjmedia/rtcp_fb.h>
#include <pjmedia/transport.h>
#include <pjmedia/stream_common.h>
#include <pj/sock.h>

PJ_BEGIN_DECL

/**
 * @defgroup PJMED_STRM Streams
 * @ingroup PJMEDIA_PORT
 * @brief Communicating with remote peer via the network
 * @{
 *
 * A media stream is a bidirectional multimedia communication between two
 * endpoints. It corresponds to a media description (m= line) in SDP
 * session descriptor.
 *
 * A media stream consists of two unidirectional channels:
 *  - encoding channel, which transmits unidirectional media to remote, and
 *  - decoding channel, which receives unidirectional media from remote.
 *
 * A media stream exports media port interface (see @ref PJMEDIA_PORT)
 * and application normally uses this interface to interconnect the stream
 * to other PJMEDIA components.
 *
 * A media stream internally manages the following objects:
 *  - an instance of media codec (see @ref PJMEDIA_CODEC),
 *  - an @ref PJMED_JBUF,
 *  - two instances of RTP sessions (#pjmedia_rtp_session, one for each
 *    direction),
 *  - one instance of RTCP session (#pjmedia_rtcp_session),
 *  - and a reference to media transport to send and receive packets
 *    to/from the network (see @ref PJMEDIA_TRANSPORT).
 *
 * Streams are created by calling #pjmedia_stream_create(), specifying
 * #pjmedia_stream_info structure in the parameter. Application can construct
 * the #pjmedia_stream_info structure manually, or use
 * #pjmedia_stream_info_from_sdp() or #pjmedia_session_info_from_sdp()
 * functions to construct the #pjmedia_stream_info from local and remote
 * SDP session descriptors.
 *
 * Application can also use @ref PJMEDIA_SESSION to indirectly create the
 * streams.
 */

/**
 * This structure describes media stream information. Each media stream
 * corresponds to one "m=" line in SDP session descriptor, and it has
 * its own RTP/RTCP socket pair.
 */
typedef struct pjmedia_mcx_stream_info
{
    pjmedia_type type;      /**< Media type (audio, video)	    */
    pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
    pjmedia_dir dir;        /**< Media direction.		    */
    pj_sockaddr rem_addr;   /**< Remote RTP address		    */
    // pj_sockaddr rem_rtcp;   /**< Optional remote RTCP address. If
                //  sin_family is zero, the RTP address
                //  will be calculated from RTP.	    */
    // pj_bool_t rtcp_mux;     /**< Use RTP and RTCP multiplexing.     */
    // pjmedia_rtcp_fb_info loc_rtcp_fb; /**< Local RTCP-FB info.		    */
    // pjmedia_rtcp_fb_info rem_rtcp_fb; /**< Remote RTCP-FB info.		    */
    // pjmedia_codec_info fmt;     /**< Incoming codec format info.	    */
    // pjmedia_codec_param *param; /**< Optional codec param.		    */
    // unsigned		tx_pt;	    /**< Outgoing codec paylaod type.	    */
    // unsigned		rx_pt;	    /**< Incoming codec paylaod type.	    */
    // unsigned		tx_maxptime;/**< Outgoing codec max ptime.	    */
    // int		        tx_event_pt;/**< Outgoing pt for telephone-events.  */
    // int			rx_event_pt;/**< Incoming pt for telephone-events.  */
    pj_uint32_t ssrc;       /**< RTP SSRC.			    */
    pj_str_t cname;         /**< RTCP CNAME.			    */
    pj_bool_t has_rem_ssrc; /**<Has remote RTP SSRC?		    */
    pj_uint32_t rem_ssrc;   /**< Remote RTP SSRC.		    */
    pj_str_t rem_cname;     /**< Remote RTCP CNAME.		    */
    pj_uint32_t rtp_ts;     /**< Initial RTP timestamp.		    */
    pj_uint16_t rtp_seq;    /**< Initial RTP sequence number.	    */
    pj_uint8_t rtp_seq_ts_set;
    // pj_bool_t           rtcp_sdes_bye_disabled;
    /**< Disable automatic sending of RTCP
         SDES and BYE.                      */
} pjmedia_mcx_stream_info;

PJ_DECL(pj_status_t)
pjmedia_mcx_stream_info_from_sdp(pjmedia_mcx_stream_info *si,
                                 pj_pool_t *pool,
                                 pjmedia_endpt *endpt,
                                 const pjmedia_sdp_session *local,
                                 const pjmedia_sdp_session *remote,
                                 unsigned stream_idx);

/**
 * Create a media stream based on the specified parameter. After the stream
 * has been created, application normally would want to get the media port
 * interface of the streams, by calling pjmedia_stream_get_port(). The
 * media port interface exports put_frame() and get_frame() function, used
 * to transmit and receive media frames from the stream.
 *
 * Without application calling put_frame() and get_frame(), there will be
 * no media frames transmitted or received by the stream.
 *
 * @param endpt		Media endpoint.
 * @param pool		Pool to allocate memory for the stream. A large
 *			number of memory may be needed because jitter
 *			buffer needs to preallocate some storage.
 * @param info		Stream information.
 * @param tp		Stream transport instance used to transmit
 *			and receive RTP/RTCP packets to/from the underlying
 *			transport.
 * @param user_data	Arbitrary user data (for future callback feature).
 * @param p_stream	Pointer to receive the media stream.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_create(pjmedia_endpt *endpt,
                          pj_pool_t *pool,
                          const pjmedia_mcx_stream_info *info,
                          pjmedia_transport *tp,
                          void *user_data,
                          pjmedia_mcx_stream **p_stream);

/**
 * Destroy the media stream.
 *
 * @param stream	The media stream.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_destroy(pjmedia_mcx_stream *stream);

/**
 * Get the last frame type retreived from the jitter buffer.
 *
 * @param stream	The media stream.
 *
 * @return		Jitter buffer frame type.
 */
// PJ_DEF(char) pjmedia_mcx_stream_get_last_jb_frame_type(pjmedia_mcx_stream *stream);

/**
 * Get the media port interface of the stream. The media port interface
 * declares put_frame() and get_frame() function, which is the only
 * way for application to transmit and receive media frames from the
 * stream.
 *
 * @param stream	The media stream.
 * @param p_port	Pointer to receive the port interface.
 *
 * @return		PJ_SUCCESS on success.
 */
//PJ_DECL(pj_status_t)
//pjmedia_mcx_stream_get_port(pjmedia_mcx_stream *stream,
//                            pjmedia_port **p_port);

/**
 * Get the media transport object associated with this stream.
 *
 * @param st		The media stream.
 *
 * @return		The transport object being used by the stream.
 */
//PJ_DECL(pjmedia_transport *)
//pjmedia_mcx_stream_get_transport(pjmedia_mcx_stream *st);

/**
 * Start the media stream. This will start the appropriate channels
 * in the media stream, depending on the media direction that was set
 * when the stream was created.
 *
 * @param stream	The media stream.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_start(pjmedia_mcx_stream *stream);

/**
 * Get the stream info.
 *
 * @param stream	The media stream.
 * @param info		Stream info.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_get_info(const pjmedia_mcx_stream *stream,
                            pjmedia_mcx_stream_info *info);

/**
 * Get the stream statistics. See also
 * #pjmedia_stream_get_stat_jbuf()
 *
 * @param stream	The media stream.
 * @param stat		Media stream statistics.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_get_stat(const pjmedia_mcx_stream *stream,
                            pjmedia_rtcp_stat *stat);

/**
 * Reset the stream statistics.
 *
 * @param stream	The media stream.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_reset_stat(pjmedia_mcx_stream *stream);
/**
 * Pause the individual channel in the stream.
 *
 * @param stream	The media channel.
 * @param dir		Which direction to pause.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_pause(pjmedia_mcx_stream *stream,
                         pjmedia_dir dir);

/**
 * Resume the individual channel in the stream.
 *
 * @param stream	The media channel.
 * @param dir		Which direction to resume.
 *
 * @return		PJ_SUCCESS on success;
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_resume(pjmedia_mcx_stream *stream,
                          pjmedia_dir dir);

/*lihongpu add begin*/
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_set_floor_callback(pjmedia_mcx_stream *stream,
                                      void (*cb)(pjmedia_mcx_stream *,
                                                 void *user_data,
                                                 int digit, pj_str_t *floor_info),
                                      void *user_data);

pj_status_t mcx_rtp_session_send_rtcp_APP(pjmedia_transport *tp, pj_uint8_t subtype, const char *name, const pj_uint8_t *data, int datalen, pj_uint32_t ssrc);
/*lihongpu add end*/

/**
 * Get the RTP session information of the media stream. This function can be
 * useful for app with custom media transport to inject/filter some
 * outgoing/incoming proprietary packets into normal audio RTP traffics.
 * This will return the original pointer to the internal states of the stream,
 * and generally it is not advisable for app to modify them.
 *
 * @param stream	The media stream.
 *
 * @param session_info	The stream session info.
 *
 * @return		PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t)
pjmedia_mcx_stream_get_rtp_session_info(pjmedia_mcx_stream *stream,
                                        pjmedia_stream_rtp_sess_info *session_info);

/**
 * @}
 */

PJ_END_DECL

#endif	/* __PJMEDIA_MCX_STREAM_H__ */